package com.xquant.common.engine.xPP.cxf;

import com.xquant.common.engine.xPP.cxf.webservice.*;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.ConnectionType;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.jws.WebParam;
import javax.xml.ws.Holder;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author B946
 * @date 04/11/2020 14:37
 * @description:
 */
public class XQuantPPStub {

    private static final Logger logger = LoggerFactory.getLogger(XQuantPPStub.class);

    private XQuantPPSoap xQuantPPSoap;

    private String address;

    private int threads;

    private AtomicInteger queue = new AtomicInteger(0);

    public int getThreads() {
        return threads;
    }

    public void setThreads(int threads) {
        this.threads = threads;
    }

    public AtomicInteger getQueue() {
        return queue;
    }

    public void setQueue(AtomicInteger queue) {
        this.queue = queue;
    }

    public XQuantPPStub(String address, int threads) {
        this.address = address;
        this.threads = threads;
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(XQuantPPSoap.class);
        factory.setAddress(address);
        this.xQuantPPSoap = (XQuantPPSoap) factory.create();
    }

    protected void setConnectionParams(int connectionTimeOut, int receiveTimeOut) {
        org.apache.cxf.endpoint.Client proxy = ClientProxy.getClient(this.xQuantPPSoap);
        HTTPConduit client = (HTTPConduit) proxy.getConduit();
        HTTPClientPolicy policy = new HTTPClientPolicy();
        policy.setConnectionTimeout(connectionTimeOut);
        policy.setReceiveTimeout(receiveTimeOut);
        policy.setConnection(ConnectionType.KEEP_ALIVE);
        policy.setAllowChunking(false);
        client.setClient(policy);
    }

    public String getAddress() {
        return address;
    }

    public CalcEngineResponse calcEngine(CalcEngine calcEngine) {
        Holder<String> result = new Holder<>();
        Holder<XQuantWsFault> calcEngineResult = new Holder<>();
        this.xQuantPPSoap.calcEngine(calcEngine.getParam(), calcEngineResult, result);
        CalcEngineResponse calcEngineResponse = new CalcEngineResponse();
        calcEngineResponse.setCalcEngineResult(calcEngineResult.value);
        calcEngineResponse.setResult(result.value);
        return calcEngineResponse;
    }

    public TestMethodResponse testMethod(XQuantPPStubFactory factory, TestMethod testMethod) {
        TestMethodResponse testMethodResponse = new TestMethodResponse();
        try {
           /* String result = this.xQuantPPSoap.testMethod();
            testMethodResponse.setTestMethodResult(result);*/
        } catch (Exception ex) {
            logger.error(factory.getxQuantPPStub().getAddress() + " 服务未启动");
        }
        return testMethodResponse;
    }

    public RestartResponse restart(Restart restart) {
        XQuantWsFault result = this.xQuantPPSoap.restart();
        RestartResponse restartResponse = new RestartResponse();
        restartResponse.setRestartResult(result);
        return restartResponse;
    }

    public SerializeJsonFromFpMLResponse serializeJsonFromFpML(SerializeJsonFromFpML serializeJsonFromFpML) {
        Holder<String> result = new Holder<>();
        Holder<XQuantWsFault> serializeJsonFromFpMLResult = new Holder<>();
        this.xQuantPPSoap.serializeJsonFromFpML(serializeJsonFromFpML.getFpml(), serializeJsonFromFpMLResult, result);
        SerializeJsonFromFpMLResponse serializeJsonFromFpMLResponse = new SerializeJsonFromFpMLResponse();
        serializeJsonFromFpMLResponse.setSerializeJsonFromFpMLResult(serializeJsonFromFpMLResult.value);
        serializeJsonFromFpMLResponse.setResult(result.value);
        return serializeJsonFromFpMLResponse;
    }

    public RunTaskResponse runTask(RunTask runTask) {
        XQuantWsFault result = this.xQuantPPSoap.runTask(runTask.getParam());
        RunTaskResponse runTaskResponse = new RunTaskResponse();
        runTaskResponse.setRunTaskResult(result);
        return runTaskResponse;
    }

    public NotifyDataResponse notifyData(NotifyData notifyData) {
        XQuantWsFault result = this.xQuantPPSoap.notifyData(notifyData.getParam());
        NotifyDataResponse notifyDataResponse = new NotifyDataResponse();
        notifyDataResponse.setNotifyDataResult(result);
        return notifyDataResponse;
    }



    public CalcVolSurfaceRatesResponse calcVolSurfaceRates(CalcVolSurfaceRates calcVolSurfaceRates){
        Holder<CalcVolSurfaceRatesResult> result = new Holder<>();
        Holder<XQuantWsFault> calcVolSurfaceRatesResult = new Holder<>();
        this.xQuantPPSoap.calcVolSurfaceRates(calcVolSurfaceRates.getParam(), calcVolSurfaceRatesResult, result);
        CalcVolSurfaceRatesResponse calcVolSurfaceRatesResponse = new CalcVolSurfaceRatesResponse();
        calcVolSurfaceRatesResponse.setCalcVolSurfaceRatesResult(calcVolSurfaceRatesResult.value);
        calcVolSurfaceRatesResponse.setResult(result.value);
        return calcVolSurfaceRatesResponse;
    }

    /**
     * 波动率曲面插值
     * @param calcVolSurfaceRateBase64
     * @return
     */
    public CalcVolSurfaceRateBase64Response calcVolSurfaceRateBase64(CalcVolSurfaceRateBase64 calcVolSurfaceRateBase64){
        Holder<String> result = new Holder<>();
        Holder<XQuantWsFault> calcVolSurfaceRatesResult = new Holder<>();
        this.xQuantPPSoap.calcVolSurfaceRateBase64(calcVolSurfaceRateBase64.getParam(), calcVolSurfaceRatesResult, result);
        CalcVolSurfaceRateBase64Response calcVolSurfaceRateBase64Response = new CalcVolSurfaceRateBase64Response();
        calcVolSurfaceRateBase64Response.setCalcVolSurfaceRateBase64Result(calcVolSurfaceRatesResult.value);
        calcVolSurfaceRateBase64Response.setResult(result.value);
        return calcVolSurfaceRateBase64Response;
    }

    /**
     * 利率曲线插值
     * @param calcCurveRatesBase64
     * @return
     */
    public CalcCurveRatesBase64Response calcCurveRateBase64(CalcCurveRatesBase64 calcCurveRatesBase64){
        Holder<CalcCurveRatesResult> result = new Holder<>();
        Holder<XQuantWsFault> CalcCurveRatesBase64Result = new Holder<>();
        this.xQuantPPSoap.calcCurveRatesBase64(calcCurveRatesBase64.getParam(), CalcCurveRatesBase64Result, result);
        CalcCurveRatesBase64Response calcCurveRatesBase64Response = new CalcCurveRatesBase64Response();
        calcCurveRatesBase64Response.setCalcCurveRatesBase64Result(CalcCurveRatesBase64Result.value);
        calcCurveRatesBase64Response.setResult(result.value);
        return calcCurveRatesBase64Response;
    }


    /**
     * 分红曲线插值
     * @param calcDivCurveRatesBase64
     * @return
     */
    public CalcDivCurveRatesBase64Response calcDivCurveRatesBase64(CalcDivCurveRatesBase64 calcDivCurveRatesBase64){
        Holder<CalcDivCurveRatesResult> result = new Holder<>();
        Holder<XQuantWsFault> calcDivCurveRatesBase64Result = new Holder<>();
        this.xQuantPPSoap.calcDivCurveRatesBase64(calcDivCurveRatesBase64.getParam(), calcDivCurveRatesBase64Result, result);
        CalcDivCurveRatesBase64Response calcDivCurveRatesBase64Response = new CalcDivCurveRatesBase64Response();
        calcDivCurveRatesBase64Response.setCalcDivCurveRatesBase64Result(calcDivCurveRatesBase64Result.value);
        calcDivCurveRatesBase64Response.setResult(result.value);
        return calcDivCurveRatesBase64Response;
    }


    public EquityOptionImplVolResponse calcEquityOptionImplVol(EquityOptionImplVolParam equityOptionImplVolParam){
        Holder<EquityOptionImplVolResult> result = new Holder<>();
        Holder<XQuantWsFault> calcVolSurfaceRatesResult = new Holder<>();
        this.xQuantPPSoap.calcEquityOptionImplVol(equityOptionImplVolParam, calcVolSurfaceRatesResult, result);
        EquityOptionImplVolResponse equityOptionImplVolResponse = new EquityOptionImplVolResponse();
        equityOptionImplVolResponse.setEquityOptionImplVolResult(calcVolSurfaceRatesResult.value);
        equityOptionImplVolResponse.setResult(result.value);
        return equityOptionImplVolResponse;
    }

    public CalcEventInfoResponse calcEventInfo(EventInfoParam eventInfoParam){
        Holder<EventInfoResult> result = new Holder<>();
        Holder<XQuantWsFault> calcEventInfoResult = new Holder<>();
        this.xQuantPPSoap.calcEventInfo(eventInfoParam, calcEventInfoResult, result);
        CalcEventInfoResponse calcEventInfoResponse = new CalcEventInfoResponse();
        calcEventInfoResponse.setCalcEventInfoResult(calcEventInfoResult.value);
        calcEventInfoResponse.setResult(result.value);
        return calcEventInfoResponse;
    }

    /*反算合约要素*/
    public CalcEquityOptionImplContractResponse calcEquityOptionImplContract(EquityOptionImplContractParam param){
        Holder<XQuantWsFault> calcEquityOptionImplContractResult = new Holder<>();
        Holder<EquityOptionImplContractResult> result = new Holder<>();
        this.xQuantPPSoap.calcEquityOptionImplContract(param,calcEquityOptionImplContractResult,result);
        CalcEquityOptionImplContractResponse calcEquityOptionImplContractResponse = new CalcEquityOptionImplContractResponse();

        calcEquityOptionImplContractResponse.setResult(result.value);
        calcEquityOptionImplContractResponse.setCalcEquityOptionImplContractResult(calcEquityOptionImplContractResult.value);

        return calcEquityOptionImplContractResponse;
    }
}
